﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lilium.LParse
{
    public sealed class StringParserState: ParserState<char>
    {
        public StringParserState(string value)
        {
            if (value == null) throw new ArgumentNullException("value");

            m_Value = value;

            if (value.Length != 0)
            {
                Current = Value[0];
            }
            else
            {
                Eof = true;
            }
        }

        public override void CancelBookmark(long bookmark)
        {   // no actions needed
        }

        public override long CreateBookmark()
        {
            return Position;
        }

        public override long CurrentBookmark()
        {
            return Position; // position is always bookmarkable.
        }

        public override void Next()
        {
            var length = Value.Length;
            if (Position != length)
            {
                Position++;
                DiscardErrors();
                if (Position != length)
                {
                    Current = Value[Position];
                }
                else
                {
                    Eof = true;
                }
            }
        }

        public override void RestoreBookmark(long bookmark)
        {
            Position = (int)bookmark;
            if (Position != Value.Length)
            {
                Eof = false;
                Current = Value[Position];
            }
            else
            {
                Eof = true;
            }
        }

        #region private int Position

        private int m_Position;

        public int Position
        {
            get { return m_Position; }
            private set { m_Position = value; }
        }

        #endregion

        protected override string ShowPosition()
        {
            return Position.ToString();
        }

        #region private string Value

        private readonly string m_Value;

        private string Value
        {
            get
            {
                return m_Value;
            }
        }

        #endregion
    }
}